מה ההבדל?
נ.ב. תוסיפו גם Service. :-)
5 תשובות
הכוונה היא למשהו שונה בכל אחד מהמקרים
model מייצג נתונים שהקונטרולר מעביר לוויו (או שהוויו קורא, או מאזין לשינויים בהם). כאן עדיין אין שום קשר למסד נתונים או לשפה כלשהי. הכוונה כאן היא נטו לנתונים. המודל מגיע מעולם הMVC ואין לו שום קשר למסד, לכן השימוש במילה מודל בהקשר של מחלקה עם קישור למסד, כפי שעושים את זה היום רוב הפריימוורקים, היא קצת מוטעית.
בפריימוקים מסוימים, בינהם לאראול, למחלקות שמייצגות טיפוס נתונים הוסיפו קישור למסד, ככה שלמחלקה נוספות פעולות כמו לשמור, לעדכן וכו'. לתבנית העיצוב הזו קוראים active record, כלומר רשומה פעילה שאפשר לשנות והשינוי יגיע ישירות למסד.
המונח repository יותר פשוט ומתכוון למישהו שמנהל נתונים בתוך אוסף כלשהו ומספק גישה אליהם באמצעות מתודות שונות.. למשל מחלקה שמכילה מערך ומספקת מתודות לגישה אליו תהיה ריפוזיטורי.מחלקה שמייצגת קובץ יכולה להיות ריפוזיטורי שמכיל נתונים, כאשר ברוב המקרים הכוונה היא למחלקה עם פעולות כמו לשלוף נתונים, להכניס נתונים וכו'. כאן יש הבדל עם האקטיב רקורד, לנתונים עצמם אין שום פעולות, הם בסך הכול DTO ולא עושים שום דבר. מצד שני, מחלקה אחרת מספקת מתודות כמו שלוף את כל המשתמשים או את משתמש לפי ID מסוים ושמור משתמש.
provider זה לפעמים שם מטעה היות שקשה להבין מה זה אומר באופן כללי. זהו לא שם של תבנית עיצוב והוא כנראה ספציפי למקרה שלך, בדיוק כפי שהמילה manager לא אומרת שום דבר על מהות הפעולה של המחלקה. במקרה של database provider הכוונה היא לרוב לחיבור למסד עצמו ובPHP ישנם כמה פרווידרים שונים לחיבורים. פרווידר שמספק חיבור ל mysql, אחד שמספק חיבור ל postgres וכו'. כל אחד מאלו נחשב לפרווידר. לא מוכר לי שום שימוש מקובל בהקשר של נתונים, אבל כנראה שכאן התכוונו לפטרן ריפוזיטורי, בתור משהו שמסוגל להחזיר מידע או לקבל מידע לפי דרישה.
service גם כן לא קשור לנתונים ובדרך כלל הכוונה היא שוב פעם לריפוזיטורי, לרוב כשהריפוזיטורי איננו לוקאלי, למשל דרך האינטרנט. מחלקה שמטרה שלה היא פשוט לשלוח בקשות rest לשרת אחר לפי פעולות שאתה מפעיל עליה יכולה להיקרא service.
@intval תודה רבה על התשובה המפורטת. בלבלו אותי כשלמדתי MVC. בעצם הקונטרולר הוא זה שבוחר את המימוש לרפוזיטורי, שהוא שכבה נפרדת של גישה לבסיס נתונים / קובץ CSV / וואטבר.
כדי להיות בטוח שאני לא טועה, יש בעיות רעיוניות בקוד הבא?
* User actions logger
**/
interface UserLoggerInterface implements LoggerInterface { ... }
class DatabaseUserLogger implements UserLoggerInterface { ... }
/******** User ********/
interface UserInterface
{
public function __construct(UseRepositoryrInterface $repo, UserLoggerInterface $userLogger);
public function repository(UseRepositoryrInterface $repo = null); // get/set repository
public function getUserName();
public function getFullName();
public function getPassword();
public function setUserName();
public function setFullName()
public function setPassword();
public function save(); // $this->repository()-save($this)
}
abstract class AbstractUser implements UserInterface { ... }
class AuthorizedUser extends AbstractUser { ... }
/******** Repositories ********/
interface UserRepositoryInterface
{
public function posts(); // QueryBuilder
public function save(UserInterface $user);
public function find($id);
// ...
}
class EloquentUserRepository extends EloquentRepository implements UseRepositoryrInterface { }
לא ממש ברור לי מה עושה הריפוזיטורי בתוך מחלקה שמייצגת משתמש, או הלוגר. אם אתה צריך לוגינג, תעשה אותו במקום שבו אתה מפעיל את מתודות שינוי השם, לא מתוך המתודה שמשנה את השם.
אם אתה מנסה לעשות active record זה בסדר שיש מתודות אחרות בתוך מחלקת היוזר, אבל ב active record בדרך כלל עובדים בלי ריפוזיטורי.
> אם אתה צריך לוגינג, תעשה אותו במקום שבו אתה מפעיל את מתודות שינוי השם, לא מתוך המתודה שמשנה את השם.
וזה אומר שאני אצטרך לעשות את זה בכל מקום בנפרד. בשביל מה?
> אם אתה מנסה לעשות active record זה בסדר שיש מתודות אחרות בתוך מחלקת היוזר, אבל ב active record בדרך כלל עובדים בלי ריפוזיטורי.
להפך, אני מנסה לעבוד עם רפוזיטורים, ולא להתקבע לסוג אחסון נתונים מסוים. אני רוצה להפריד את זה.